/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fourbox;

import fourbox.ProtocolMessage.FourFileVisitor;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author hartono
 */
public class FUtil {

    public static boolean deletePaths(Path path) {
        try {
            Files.walkFileTree(path, new SimpleFileVisitor<Path>() {

                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
                        throws IOException {
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    //                System.out.println("FILEEE " + file);
                    //                register(file);                    
                    Files.delete(file);
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                }
            });
            return true;
        } catch (IOException ex) {
            Logger.getLogger(FUtil.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public static String byteArrayToString(byte[] arr) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < arr.length - 1; i++) {
            sb.append((char) arr[i]);
            sb.append(' ');
        }
        sb.append(arr[arr.length - 1]);
        return sb.toString();
    }

    public static byte[] usernameToByteArray(String username) {
        byte[] retval = new byte[20];
        byte[] uByte = username.getBytes();
        System.arraycopy(uByte, 0, retval, 0, uByte.length);
        return retval;
    }

    public static byte[] passwordToByteArray(String password) {
        byte[] retval = new byte[35];
        byte[] pByte = password.getBytes();
        System.arraycopy(pByte, 0, retval, 0, pByte.length);
        return retval;
    }

    public static ArrayList<Metafile> getListFilesInServer(String contextPath, Path path) {
        try {
            ArrayList<Metafile> retval = new ArrayList<Metafile>();

            FourFileVisitor visitor = new FourFileVisitor();
            Files.walkFileTree(path, visitor);
            for (int i = 0; i < visitor.list.size(); i++) {
                Path p = (Path) visitor.list.get(i);
                Metafile m = Metafile.createMetafile(contextPath, p.toFile());
                retval.add(m);
            }
            retval.remove(0);
            return retval;

        } catch (IOException ex) {
            Logger.getLogger(FUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;

    }

    public ArrayList<Metafile> getDirDiffs(ArrayList<Metafile> dirs, ArrayList<Metafile> comparator) {
        ArrayList<Metafile> retval = new ArrayList<Metafile>();
        for (Metafile comp : comparator) {

            boolean found = false;
            for (Metafile newM : dirs) {
                if (comp.directory.equals(newM.directory)) {

                    found = true;
                    break;
                }
            }

            if (found) {
            } else {
//                System.out.println("File not found, deleted");
                // file tidak ditemukan
                // artinya file lama oldM sudah didelete
                comp.status = Metafile.DELETED;
                retval.add(comp);
            }
        }

        // pengecekan file baru terhadap file lama
        for (Metafile dir : dirs) {

            boolean found = false;
            Metafile old = null;
            for (Metafile oldM : comparator) {
                if (dir.directory.equals(oldM.directory)) {
                    old = oldM;
                    found = true;
                    break;
                }
            }

            if (found) {
                // cek sum dulu
                // kalo beda, berarti berubah
                if (dir.size != old.size) {
//                    System.out.println("File updated");
                    dir.status = Metafile.UPDATED;
                    retval.add(dir);
                }
                // cek tanggal
                // kalo lebih besar, lebih baru
                // kalo lebih kecil, lebih lama
                // kalo sama, yasudah lah                

            } else {
//                System.out.println("File not found, create new file");
                // not found
                // berarti ada file baru
                dir.status = Metafile.NEW;
                retval.add(dir);
            }
        }


        return retval;
    }

    public static void move(Path from, Path to) throws IOException {
        validate(from);
        Files.walkFileTree(from, new CopyDirVisitor(from, to));
        Files.walkFileTree(from, new DeleteDirVisitor(from));
    }

    private static void validate(Path... paths) {
        for (Path path : paths) {
            Objects.requireNonNull(path);
            if (!Files.isDirectory(path)) {
                throw new IllegalArgumentException(String.format("%s is not a directory", path.toString()));
            }
        }
    }

    public static String md5enc(String input) throws NoSuchAlgorithmException {
        String result  =input;
        
//        java.security.MessageDigest md = null;
//        input = (inp.getBytes());
//        try {
//            md = java.security.MessageDigest.getInstance("MD5");
//        } catch (java.security.NoSuchAlgorithmException ex) {
//            System.out.println(ex);
//        }
//        output = md.digest(input);
//        return byte2hex(output);
        MessageDigest md = MessageDigest.getInstance("MD5"); //or "SHA-1"
        md.update(input.getBytes());
        BigInteger hash = new BigInteger(1, md.digest());
        result = hash.toString(16);
        while (result.length() < 32) {
            result = "0" + result;
        }

        return result;
    }

    public static String byte2hex(byte[] b) {
        String o = "";
        for (int i = 0; i < b.length; i++) {
            char c = Long.toHexString(new Byte(b[i]).longValue()).charAt(0);
            o += c;
        }
        return o;
    }
}
